package deng.ejbtx.ejb;

import java.io.File;
import java.io.FilenameFilter;
import java.io.Serializable;
import java.util.Collection;

import javax.annotation.Resource;
import javax.ejb.Local;
import javax.ejb.SessionContext;
import javax.ejb.Stateless;
import javax.ejb.Timeout;
import javax.ejb.Timer;

import org.apache.log4j.Logger;

import deng.pojo.GroovyFilePollerAction;

@Stateless
@Local
public class FilePollerTimerBeanImpl implements FilePollerTimerBean {
	private static final String DEFAULT_ARCHIVE_DIR_NAME = ".archive";
	private static Logger logger = Logger.getLogger(FilePollerTimerBeanImpl.class);
	
	@Resource
	private SessionContext sessionCtx;
	private GroovyFilePollerAction groovyFilePollerAction;
		
	public static class FilePollerInfo implements Serializable {
		private static final long serialVersionUID = 1L;
		public File pollingDirectory;
		public File archiveDirectory;
		public File groovyScriptFile;		
	}
	
	private File getArchiveDir(File pollingDir) {
		File archiveDirectory = new File(pollingDir, DEFAULT_ARCHIVE_DIR_NAME);
		if (!archiveDirectory.exists()) {
			logger.info("Creating archive directory " + archiveDirectory);
			archiveDirectory.mkdirs();
		}
		return archiveDirectory;
	}
	
	@Override
	public void createTimer(int delay, int period, String pollingDirName, String groovyScriptFileName) {
		logger.info("Creating EJB Timer with period=" + period);
		
		FilePollerInfo info = new FilePollerInfo();
		info.pollingDirectory = new File(pollingDirName);
		info.archiveDirectory = getArchiveDir(info.pollingDirectory);
		info.groovyScriptFile = new File(groovyScriptFileName);
		
		if (groovyFilePollerAction == null) {
			logger.info("Creating groovyFilePollerAction instance for " + this);
			groovyFilePollerAction = new GroovyFilePollerAction();
		}
		groovyFilePollerAction.setScriptFile(info.groovyScriptFile);
		groovyFilePollerAction.initGroovyEngine();
		
		Timer timer = sessionCtx.getTimerService().createTimer(delay, period, info);
		logger.debug("EJB Timer created " + timer);
	}

	@Override
	public void stopTimer() {
		Collection<?> timers = sessionCtx.getTimerService().getTimers();
		for (Object timer : timers) {
			logger.debug("Stopping EJB Timer " + timer);
			((Timer)timer).cancel();
		}
	}
	
	@Timeout
	public void onTimer(Timer timer) {
		try {
			logger.debug("Running filePollerTask on timer: " + timer);
			
			FilePollerInfo info = (FilePollerInfo)timer.getInfo();		
			File pollingDirectory = info.pollingDirectory;
			final File archiveDirectory = info.archiveDirectory;
			FilenameFilter archiveDirFilter = new FilenameFilter(){
				@Override
				public boolean accept(File dir, String name) {
					return !name.equals(archiveDirectory.getName());
				}			
			};
			
			logger.debug("Polling dir " + pollingDirectory);
			//logger.debug("this " + this);
			File files [] = pollingDirectory.listFiles(archiveDirFilter);
			if (files != null && files.length > 0) {
				File script = info.groovyScriptFile;
				groovyFilePollerAction.setScriptFile(script);		
				logger.debug("Preparing groovyScriptFile " + script);
				for (File file : files) {
					logger.info("Found file " + file);
					groovyFilePollerAction.onFile(file);
					file.renameTo(new File(archiveDirectory, file.getName()));
				}
				
			}
		} catch (Throwable cause) {
			//jboss doesn't display the stack trace for some reason :(
			logger.error("Failed to run timer task.", cause);
		}
	}
}
